from typing import List, Type

from emi.bar.data import BarCustom, Interval
from emi.bar.storage.model import BaseDBModel
from emi.core.DBSource import DBSource, PeeweeModelSource
from emi.util import SqliteUtil
import peewee
from datetime import datetime

class BarCustomModel(BaseDBModel):

    symbol: int = peewee.TextField()
    datetime:datetime = peewee.TimestampField()
    interval: int = peewee.SmallIntegerField()

    _int1: int = peewee.IntegerField(default=-1)
    _int2: int = peewee.IntegerField(default=-1)
    _int3: int = peewee.IntegerField(default=-1)

    _float1: int = peewee.FloatField(default=None,null=True)
    _float2: int = peewee.FloatField(default=None,null=True)
    _float3: int = peewee.FloatField(default=None,null=True)

    _str1: str = peewee.TextField(default=None,null=True)
    _str2: str = peewee.TextField(default=None,null=True)
    _str3: str = peewee.TextField(default=None,null=True)

    core_data: bytes = peewee.BlobField(null=True)



    @staticmethod
    def from_data(bar: BarCustom):

        db_bar = BarCustomModel()
        db_bar.symbol = bar.symbol
        db_bar.interval = bar.interval.value
        db_bar.datetime = bar.datetime

        db_bar._int1 = bar._int1
        db_bar._int2 = bar._int2
        db_bar._int3 = bar._int3

        db_bar._float1 = bar._float1
        db_bar._float2 = bar._float2
        db_bar._float3 = bar._float3

        db_bar._str1 = bar._str1
        db_bar._str2 = bar._str2
        db_bar._str3 = bar._str3
        db_bar.core_data = bar.get_blob()

        return db_bar

    def to_bar(self, class_type: Type[BarCustom]):
        interval = Interval(self.interval)
        #time = datetime(self.datetime.year,self.datetime.month,self.datetime.day)
        bar: BarCustom = class_type(interval=interval, datetime=self.datetime, symbol=self.symbol)

        bar._int1 = self._int1
        bar._int2 = self._int2
        bar._int3 = self._int3

        bar._float1 = self._float1
        bar._float2 = self._float2
        bar._float3 = self._float3

        bar._str1 = self._str1
        bar._str2 = self._str2
        bar._str3 = self._str3
        bar.set_blob(self.core_data,form_storage=True)

        return bar


class BarCustomDB:

    def __init__(self,source:DBSource,indexes_desc = None,table_name = None):
        if indexes_desc is None:
            indexes_desc = (
                    (("symbol", "datetime","interval"), True),
                )
        if table_name is None:
            table_name = 'bar_custom'
        self.source = source.init_peewee(table_name,BarCustomModel,indexes=indexes_desc,ignore_inited=True)


    def get_db_source(self)->PeeweeModelSource[BarCustomModel]:
        return self.source

    def get_symbol_list(self) -> List[str]:
        """
        返回所有的symbol列表
        """
        with self.source.use_peewee() as db_model:
            s = (db_model.select(db_model.symbol).distinct())
            return [v.symbol for v in s]

    def save_bars(self,bars:List[BarCustom]):
        """
        保存Bar数据。
        """
        ds = [BarCustomModel.from_data(i) for i in bars]
        with self.source.use_peewee() as db_model:
            db_model.save_all(ds)

    def size(self, symbol: str = None) -> int:
        with self.source.use_peewee() as db_model:
            if symbol is None:
                return db_model.select().count()
            else:
                return db_model.select().where(db_model.symbol == symbol).count()

    def clear(self, symbol: str = None):
        with self.source.use_peewee() as db_model:
            if not symbol is None:
                db_model.delete().where(
                    (db_model.symbol == symbol)
                ).execute()
            else:
                ##情况表
                db_model.drop_table()
                db_model.create_table()

    def clear_before(self, time: datetime):
        with self.source.use_peewee() as db_model:
            db_model.delete().where(
                (db_model.datetime <= time)
            ).execute()